import option
from option import Option
import pickle
from helpers import fmt
from math import sqrt
import helpers
import gtk

class Session:
        class options(option.ContainerClass):
                data={}
                pass

        def __init__(self):
                self.options().worst=-1.0
                self.options().best=-1.0
                self.options().average=-1.0
                self.options().bestavg=-1.0
                self.options().total_num=0
                self.options().mean=-1.0
                self.options().avg_len=12
                self.options().scores=[]
                self.options().bestavg_start=-1
                self.options().bestavg_end=-1
		self.options().deviation=-1.0

		Option().windowMain.sideText.insert(0,self.side_text)
                self.repopulate_scores()

        def teardown(self):
		Option().windowMain.sideText.remove(self.side_text)
        
        def besttime(self,t):
                if t<self.options().best or self.options().best==-1.0:
                        self.options().best=t
                        return True
                else:
                        return False


        def bestavg(self,t):
                if t<self.options().bestavg or self.options().bestavg==-1.0:
                        self.options().bestavg=t
                        return True
                else:
                        return False

        def worsttime(self,t):
                if t>self.options().worst or self.options().worst==-1.0:
                        self.options().worst=t
                        return True
                else:
                        return False

        def _calc_avg(self,start,end,prop=False): #prop=True => ommit worst and best time
                if start>end or start<0 or end>=len(self.options().scores): return -1.00
                avg=0.00
                worst=(-1,0.0)
                best=(-1,999999.9)
                scores=self.options().scores

                for i in range(start,end+1):
#                       print i
                        val=float(scores[i])
                        avg+=val
                        if val>worst[1]:
                                worst=(i,val)
                        if val<best[1]:
                                best=(i,val)

                num=end-start+1
                if prop:
                        if worst[0]==best[0]:
                                avg-=worst[1]
                                num-=1
                        else:
                                avg-=worst[1]+best[1]
                                num-=2
                return avg/num

        def _calc_mean(self):
                return self._calc_avg(0,len(self.options().scores)-1)
        
        def process_time(self,t):
                t=round(t,2)
                self.options().scores.append(t)
                self.options().total_num+=1

                self.options().mean=self._calc_mean()

                if len(self.options().scores)>=self.options().avg_len:
                        self.options().average=self._calc_avg(len(self.options().scores)-12,len(self.options().scores)-1,True)
                        if self.bestavg(self.options().average):
                                self.options().bestavg_start=len(self.options().scores)-11
                                self.options().bestavg_end=len(self.options().scores)


                if len(self.options().scores)==2:
                        if float(self.options().scores[1])>float(self.options().scores[0]):
                                self.besttime(float(self.options().scores[0]))
                                self.worsttime(float(self.options().scores[1]))
                        else:
                                self.besttime(float(self.options().scores[1]))
                                self.worsttime(float(self.options().scores[0]))
                if len(self.options().scores)>2:
                        if not self.besttime(t):
                                self.worsttime(t)

                self.calculateDeviation()

	def calculateDeviation(self):
		sum=0
		for t in self.options().scores:
			sum += (t - self.options().mean)**2

		self.options().deviation = sqrt( sum/len(self.options().scores) )

        def side_text(self):
                        return (_('SESSION'), [
                                _('Mean of')+' '+str(self.options().total_num)+': '+fmt(self.options().mean),
                                _('Avg of')+' '+str(self.options().avg_len)+': '+fmt(self.options().average),
                                _('Std. deviation')+': '+fmt(self.options().deviation),
                                _('Best time')+': '+fmt(self.options().best),
                                _('Worst time')+': '+fmt(self.options().worst),
                                _('Best average')+': '+fmt(self.options().bestavg),

                                ])

        def repopulate_scores(self):
                Option().windowMain.setScores(self.options().scores)


        def save(self,filename):
                pickle.dump(self.options().dump(),open(filename,'w+'))

        def load(self,filename):
		try:
	                data=pickle.load(open(filename))
                	self.options().dump(data)
	                self.repopulate_scores()
			Option().windowMain.refresh()
		except:
			helpers.message(_('An error occured while loading.'),gtk.MESSAGE_ERROR)

